package gamagora.game.world.backgrounds
{
	import gamagora.game.entity.OSEntity;
	import gamagora.game.world.maps.OSMap;
	
	import org.flixel.FlxG;
	
	public class OSBackgroundLayer extends OSEntity
	{
		private var _decalX:Number;
		private var _backgroundsIndices:Vector.<uint>;
		private var _nbBackgrounds:uint;
		private var _scrollEnable:Boolean;
		
		//Calcul du scroll
		private var _scrollLeftBound:Number;
		private var _scrollRightBound:Number;
		private var _currentBackgroundIndex:uint;
		private var _oldBackgroundIndex:uint;
		private var _onStart:Boolean;
		private var _onEnd:Boolean;
		private var _scrollPos:Number;
		private var _startScrollPos:Number;
		private var _endScrollPos:Number;
		
		private var _leftBackground:OSEntity;
		private var _centerBackground:OSEntity;
		private var _rightBackground:OSEntity;
		
		public function OSBackgroundLayer(decalX:Number, scrollLeftBound:Number, scrollRightBound:Number)
		{
			super(NOTHING);
			_decalX = decalX;
			_scrollLeftBound = scrollLeftBound;
			_scrollRightBound = scrollRightBound;
			_hide = true;
			_scrollEnable = true;
			
			_backgroundsIndices = new Vector.<uint>();
			_nbBackgrounds = 0;
			
			_currentBackgroundIndex = 0;
			_oldBackgroundIndex = 0;
			_scrollPos = 0;
			_startScrollPos = 0;
			_endScrollPos = 0;
		}
		
		public override function update():void
		{
			if(_scrollEnable)
			{
				//Calcul du scroll
				_onStart = _world.getPlayerX() <= _scrollLeftBound;
				_onEnd = _world.getPlayerX() >= _scrollRightBound;
				
				_scrollPos = _world.getPlayerX() * _decalX;
				_startScrollPos = (_scrollLeftBound - _world.getPlayerHalfWidth()) * _decalX;
				_endScrollPos = (_scrollRightBound - _world.getPlayerHalfWidth()) * _decalX;
				
				_currentBackgroundIndex = uint((_world.getPlayerX() + _scrollPos) / OSMap.WIDTH);
				
				//Assez de backgrounds ?
				if(_currentBackgroundIndex + 1 < _backgroundsIndices.length)
				{
					//Mise à jour des backgrounds
					if(_currentBackgroundIndex != _oldBackgroundIndex)
					{
						if(_currentBackgroundIndex > _oldBackgroundIndex) //Le joueur a avancé
						{
							if(_currentBackgroundIndex - 1 >= 0 && _leftBackground != null)
							{
								removeEntityFromWorld(_leftBackground);
							}
							
							_leftBackground = _centerBackground;	
							_centerBackground = _rightBackground;
							
							_rightBackground = 	_entities[_backgroundsIndices[_currentBackgroundIndex + 1]];
							_rightBackground.resetEntity();
							addEntityToWorld(_rightBackground);
							
						}
						else //Le joueur a reculé
						{
							removeEntityFromWorld(_rightBackground);
							
							_rightBackground = _centerBackground;
							
							_centerBackground = _leftBackground;
							
							if(_currentBackgroundIndex - 1 >= 0)
							{
								_leftBackground = _entities[_backgroundsIndices[_currentBackgroundIndex - 1]];
								_leftBackground.resetEntity();
								addEntityToWorld(_leftBackground);
							}
							else 
							{
								_leftBackground = null;
							}
						}
						
						_oldBackgroundIndex = _currentBackgroundIndex;
					}
				}
			}
			
			if(_leftBackground != null)
			{
				_leftBackground.update();
			}
			
			_centerBackground.update();
			_rightBackground.update();
		}
		
		public override function draw():void
		{
			if(_leftBackground != null)
			{
				drawBackground(_leftBackground, _currentBackgroundIndex * OSMap.WIDTH - OSMap.WIDTH);
			}
			
			drawBackground(_centerBackground, _currentBackgroundIndex * OSMap.WIDTH);
			drawBackground(_rightBackground, _currentBackgroundIndex * OSMap.WIDTH + OSMap.WIDTH);
		}
		
		//On casse le système pour ne pas ajouter tout les backgrounds d'un coup au monde
		
		public override function addToWorld():void
		{
			_inWorld = true;
			_centerBackground = _entities[_backgroundsIndices[_currentBackgroundIndex]];
			_rightBackground = _entities[_backgroundsIndices[_currentBackgroundIndex + 1]];
			
			addEntityToWorld(_centerBackground);
			addEntityToWorld(_rightBackground);
		}
		
		public override function removeFromWorld():void
		{
			_inWorld = false;
		}
		
		private function drawBackground(background:OSEntity, scroll:Number):void
		{
			if(_onStart)
			{
				background.setScroll(scroll - _startScrollPos);
			}
			else 
			{
				if(_onEnd)
				{
					background.setScroll(scroll - _endScrollPos);
				}
				else
				{
					background.setScroll(scroll - _scrollPos);
				}
			}
			
			background.draw();
		}
		
		public function hideBackgrounds(indices:Array):void
		{
			for(var i:uint=0;i<indices.length;i++)
			{
				if(indices[i] < _backgroundsIndices.length)
				{
					_backgroundsIndices[indices[i]] = _nbEntities - 1;
				}
			}
		}
		
		public function generateRandomBackgrounds(factor:uint = 5):void
		{
			var nbSamples:uint = _entities.length;
			
			// On génère "factor" fois plus de backgrounds (pour le dépassement du au scrolling)
			_nbBackgrounds = factor * nbSamples; 
			
			for(var i:uint;i<_nbBackgrounds;i++)
			{
				_backgroundsIndices.push(uint(Math.random() * nbSamples));
			}
			
			//Background invisible
			var fakeBackground:OSEntity = new OSEntity(NOTHING);
			fakeBackground.hide = true;
			add(fakeBackground);
		}
		
		public function stopScroll():void
		{
			_scrollEnable = false;	
		}
		
		public function getLayerScroll(position:Number):Number
		{
			if(_onStart)
			{
				return (position + _startScrollPos) % OSMap.WIDTH;
			}
			else 
			{
				if(_onEnd)
				{
					return (position + _endScrollPos) % OSMap.WIDTH;
				}
				else 
				{
					return (position + _scrollPos) % OSMap.WIDTH;
				}
			}
		}
	}
}
